package com.game.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class NetworkService implements Runnable {

	private final ServerSocket serverSocket;
	private final ExecutorService pool;

	private static final int timeout = 100;

	private boolean isClose;

	private ActionMap actionMap;

	private GameThread gameThread;

	public static NetworkService service;

	public NetworkService(int port, int poolSize) throws IOException {
		init();
		pool = new ThreadPoolExecutor(10, 1000, 0L, TimeUnit.MILLISECONDS,
				new LinkedBlockingQueue<Runnable>());
		serverSocket = new ServerSocket(port);
		serverSocket.setSoTimeout(timeout);
	}

	public static NetworkService get() {
		return service;
	}

	private void init() {
		actionMap = new ActionMap();
		actionMap.initActionMap();
		gameThread = new GameThread();
		gameThread.init();
		isClose = false;
		service = this;
	}

	public GameThread getGameThread() {
		return gameThread;
	}

	public Action getAction(String key) {
		return actionMap.getAction(key);
	}

	public void close() {
		System.out.println("close server");
		isClose = true;
	}

	public void run() { // run the service
		try {
			while (!isClose) {
				Socket socket = null;
				try {
					socket = serverSocket.accept();
				} catch (SocketTimeoutException e) {
				}
				if (socket != null) {
					System.out.println("connect");
					pool.execute(new SocketThread(socket));
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			pool.shutdown();
			try {
				serverSocket.close();
			} catch (IOException e) {
			}
			System.out.println("exit server");
		}
	}

}
